"""实现连接响应"""
from umq.adapters import StreamReaderAdapter
from umq.codecs import read_or_raise, bytes_to_int
from umq.errors import UMQException
from umq.mqtt.packet import CONNACK
from umq.mqtt.packet import MqttFixedHeader, MqttVariableHeader, MqttPacket


class ConnackVariableHeader(MqttVariableHeader):
    """connack variable封装"""
    __slots__ = ('session_parsent', 'return_code')

    def __init__(self, session_parsent=None, return_code=None):
        super().__init__()
        self.session_parsent = session_parsent
        self.return_code = return_code

    @classmethod
    async def from_stream(cls, reader: StreamReaderAdapter, fixed: MqttFixedHeader):
        data = await read_or_raise(reader, 2)
        session_parsent = data[0] & 0x01
        return_code = bytes_to_int(data[1])
        return cls(session_parsent, return_code)

    def __repr__(self):
        return type(self).__name__ + 'session_parsent={}, return_code={}'.format(
            self.session_parsent, self.return_code
        )


class ConnackPacket(MqttPacket):
    """connack 包封装"""

    @property
    def return_code(self):
        return self.variable_header.return_code

    @return_code.setter
    def return_code(self, return_code):
        self.variable_header.return_code = return_code

    @property
    def session_parsent(self):
        return self.variable_header.session_parsent

    @session_parsent.setter
    def session_parsent(self, session_parsent):
        self.variable_header.session_parsent = session_parsent

    def __init__(self, fixed: MqttFixedHeader = None,
                 variable: ConnackVariableHeader = None, payload=None):
        if fixed is None:
            header = MqttFixedHeader(CONNACK, 0x00)
        else:
            if fixed.packet_type is not CONNACK:
                raise UMQException('Invalid fixed packet type %s for \
                                   connack init' % fixed.packet_type)
            header = fixed
        super().__init__(header)
        self.variable_header = variable
        self.payload = None

    @classmethod
    def build(cls, session_parsent=None, return_code=None):
        v_header = ConnackVariableHeader(session_parsent, return_code)
        packet = ConnackPacket(v_header)
        return packet
